[NET] back: Simplify probing of new interfaces. There's no need
authorkfraser@localhost.localdomain <kfraser@localhost.localdomain>
Fri, 13 Oct 2006 16:10:27 +0000 (17:10 +0100)
committerkfraser@localhost.localdomain <kfraser@localhost.localdomain>
Fri, 13 Oct 2006 16:10:27 +0000 (17:10 +0100)
to watch for creation of the handle node in xenstore, as it is
written by xend when creating the backend directory as part of
the same transaction.
Signed-off-by: Keir Fraser <keir@xensource.com>
linux-2.6-xen-sparse/drivers/xen/netback/common.h
linux-2.6-xen-sparse/drivers/xen/netback/interface.c
linux-2.6-xen-sparse/drivers/xen/netback/xenbus.c

index 434ff6bcf2f8e3b4c090f4ae8dad806a32601816..34dd998663d52a4c6499fc2ea078c7a92a8ce0ed 100644 (file)
@@ -106,7 +106,7 @@ typedef struct netif_st {
 
 void netif_disconnect(netif_t *netif);
 
-netif_t *netif_alloc(domid_t domid, unsigned int handle, u8 be_mac[ETH_ALEN]);
+netif_t *netif_alloc(domid_t domid, unsigned int handle);
 int netif_map(netif_t *netif, unsigned long tx_ring_ref,
              unsigned long rx_ring_ref, unsigned int evtchn);
 
index d70955fd1bb881168cc441af7f2cc80c365de34f..a698ccc77b02fc8d03589fa49802c99d1d6c9c20 100644 (file)
@@ -126,7 +126,7 @@ static struct ethtool_ops network_ethtool_ops =
        .get_link = ethtool_op_get_link,
 };
 
-netif_t *netif_alloc(domid_t domid, unsigned int handle, u8 be_mac[ETH_ALEN])
+netif_t *netif_alloc(domid_t domid, unsigned int handle)
 {
        int err = 0, i;
        struct net_device *dev;
@@ -169,20 +169,14 @@ netif_t *netif_alloc(domid_t domid, unsigned int handle, u8 be_mac[ETH_ALEN])
                printk(KERN_WARNING "netbk: WARNING: device '%s' has non-zero "
                       "queue length (%lu)!\n", dev->name, dev->tx_queue_len);
 
-       for (i = 0; i < ETH_ALEN; i++)
-               if (be_mac[i] != 0)
-                       break;
-       if (i == ETH_ALEN) {
-               /*
-                * Initialise a dummy MAC address. We choose the numerically
-                * largest non-broadcast address to prevent the address getting
-                * stolen by an Ethernet bridge for STP purposes.
-                * (FE:FF:FF:FF:FF:FF)
-                */ 
-               memset(dev->dev_addr, 0xFF, ETH_ALEN);
-               dev->dev_addr[0] &= ~0x01;
-       } else
-               memcpy(dev->dev_addr, be_mac, ETH_ALEN);
+       /*
+        * Initialise a dummy MAC address. We choose the numerically
+        * largest non-broadcast address to prevent the address getting
+        * stolen by an Ethernet bridge for STP purposes.
+        * (FE:FF:FF:FF:FF:FF)
+        */ 
+       memset(dev->dev_addr, 0xFF, ETH_ALEN);
+       dev->dev_addr[0] &= ~0x01;
 
        rtnl_lock();
        err = register_netdevice(dev);
index 8592ab4cb452b5ceb75ef7d9dcb3a28527374388..c61821c8f93f54e29ea4e0ac28ef3b9f04333384 100644 (file)
     printk("netback/xenbus (%s:%d) " fmt ".\n", __FUNCTION__, __LINE__, ##args)
 #endif
 
-struct backend_info
-{
+struct backend_info {
        struct xenbus_device *dev;
        netif_t *netif;
-       struct xenbus_watch backend_watch;
        enum xenbus_state frontend_state;
 };
 
 static int connect_rings(struct backend_info *);
 static void connect(struct backend_info *);
-static void maybe_connect(struct backend_info *);
-static void backend_changed(struct xenbus_watch *, const char **,
-                           unsigned int);
+static void backend_create_netif(struct backend_info *be);
 
 static int netback_remove(struct xenbus_device *dev)
 {
        struct backend_info *be = dev->dev.driver_data;
 
-       if (be->backend_watch.node) {
-               unregister_xenbus_watch(&be->backend_watch);
-               kfree(be->backend_watch.node);
-               be->backend_watch.node = NULL;
-       }
        if (be->netif) {
                netif_disconnect(be->netif);
                be->netif = NULL;
@@ -63,8 +54,7 @@ static int netback_remove(struct xenbus_device *dev)
 
 /**
  * Entry point to this code when a new device is created.  Allocate the basic
- * structures, and watch the store waiting for the hotplug scripts to tell us
- * the device's handle.  Switch to InitWait.
+ * structures and switch to InitWait.
  */
 static int netback_probe(struct xenbus_device *dev,
                         const struct xenbus_device_id *id)
@@ -83,11 +73,6 @@ static int netback_probe(struct xenbus_device *dev,
        be->dev = dev;
        dev->dev.driver_data = be;
 
-       err = xenbus_watch_path2(dev, dev->nodename, "handle",
-                                &be->backend_watch, backend_changed);
-       if (err)
-               goto fail;
-
        do {
                err = xenbus_transaction_start(&xbt);
                if (err) {
@@ -108,7 +93,8 @@ static int netback_probe(struct xenbus_device *dev,
                        goto abort_transaction;
                }
 
-               err = xenbus_printf(xbt, dev->nodename, "feature-rx-copy", "%d", 1);
+               err = xenbus_printf(xbt, dev->nodename,
+                                   "feature-rx-copy", "%d", 1);
                if (err) {
                        message = "writing feature-copying";
                        goto abort_transaction;
@@ -123,9 +109,11 @@ static int netback_probe(struct xenbus_device *dev,
        }
 
        err = xenbus_switch_state(dev, XenbusStateInitWait);
-       if (err) {
+       if (err)
                goto fail;
-       }
+
+       /* This kicks hotplug scripts, so do it immediately. */
+       backend_create_netif(be);
 
        return 0;
 
@@ -175,48 +163,30 @@ static int netback_uevent(struct xenbus_device *xdev, char **envp,
 }
 
 
-/**
- * Callback received when the hotplug scripts have placed the handle node.
- * Read it, and create a netif structure.  If the frontend is ready, connect.
- */
-static void backend_changed(struct xenbus_watch *watch,
-                           const char **vec, unsigned int len)
+static void backend_create_netif(struct backend_info *be)
 {
        int err;
        long handle;
-       struct backend_info *be
-               = container_of(watch, struct backend_info, backend_watch);
        struct xenbus_device *dev = be->dev;
 
-       DPRINTK("");
+       if (be->netif != NULL)
+               return;
 
        err = xenbus_scanf(XBT_NIL, dev->nodename, "handle", "%li", &handle);
-       if (XENBUS_EXIST_ERR(err)) {
-               /* Since this watch will fire once immediately after it is
-                  registered, we expect this.  Ignore it, and wait for the
-                  hotplug scripts. */
-               return;
-       }
        if (err != 1) {
                xenbus_dev_fatal(dev, err, "reading handle");
                return;
        }
 
-       if (be->netif == NULL) {
-               u8 be_mac[ETH_ALEN] = { 0, 0, 0, 0, 0, 0 };
-
-               be->netif = netif_alloc(dev->otherend_id, handle, be_mac);
-               if (IS_ERR(be->netif)) {
-                       err = PTR_ERR(be->netif);
-                       be->netif = NULL;
-                       xenbus_dev_fatal(dev, err, "creating interface");
-                       return;
-               }
-
-               kobject_uevent(&dev->dev.kobj, KOBJ_ONLINE);
-
-               maybe_connect(be);
+       be->netif = netif_alloc(dev->otherend_id, handle);
+       if (IS_ERR(be->netif)) {
+               err = PTR_ERR(be->netif);
+               be->netif = NULL;
+               xenbus_dev_fatal(dev, err, "creating interface");
+               return;
        }
+
+       kobject_uevent(&dev->dev.kobj, KOBJ_ONLINE);
 }
 
 
@@ -249,11 +219,9 @@ static void frontend_changed(struct xenbus_device *dev,
                break;
 
        case XenbusStateConnected:
-               if (!be->netif) {
-                       /* reconnect: setup be->netif */
-                       backend_changed(&be->backend_watch, NULL, 0);
-               }
-               maybe_connect(be);
+               backend_create_netif(be);
+               if (be->netif)
+                       connect(be);
                break;
 
        case XenbusStateClosing:
@@ -279,15 +247,6 @@ static void frontend_changed(struct xenbus_device *dev,
 }
 
 
-/* ** Connection ** */
-
-
-static void maybe_connect(struct backend_info *be)
-{
-       if (be->netif && (be->frontend_state == XenbusStateConnected))
-               connect(be);
-}
-
 static void xen_net_read_rate(struct xenbus_device *dev,
                              unsigned long *bytes, unsigned long *usec)
 {